package xin.marcher.wind.process.controller.admin;

import cn.hutool.core.util.StrUtil;
import org.springframework.web.bind.annotation.*;
import xin.marcher.framework.common.exception.BusinessException;
import xin.marcher.framework.common.util.validation.ParamCheckUtil;
import xin.marcher.framework.common.web.response.BaseResult;
import xin.marcher.wind.process.domain.dto.ProcessConfigDTO;
import xin.marcher.wind.process.domain.dto.ProcessNodeLinkedDTO;
import xin.marcher.wind.process.domain.request.DeleteProcessConfigRequest;
import xin.marcher.wind.process.domain.request.SaveProcessConfigRequest;
import xin.marcher.wind.process.enums.InvokeMethodEnum;
import xin.marcher.wind.process.enums.ProcessEnableEnum;
import xin.marcher.wind.process.enums.ProcessErrorCodeEnum;
import xin.marcher.wind.process.enums.ProcessTypeEnum;
import xin.marcher.wind.process.service.ProcessConfigService;

import javax.annotation.Resource;
import java.util.List;

/**
 * 流程配置 前端控制器
 */
@RestController
@RequestMapping("/process-config")
public class ProcessConfigController {

    @Resource
    private ProcessConfigService processConfigService;

    /**
     * 保存流程配置
     * @param request 请求
     * @return 响应
     */
    @PostMapping("/")
    public BaseResult<Boolean> save(@RequestBody SaveProcessConfigRequest request) {

        // 1、校验入参
        ParamCheckUtil.checkIntAllowableValues(request.getType(), ProcessTypeEnum.allowableValues(),"type");
        ParamCheckUtil.checkStringNonEmpty(request.getName(), ProcessErrorCodeEnum.PROCESS_NAME_IS_EMPTY);
        ParamCheckUtil.checkStringNonEmpty(request.getXmlName(), ProcessErrorCodeEnum.PROCESS_XML_NAME_IS_EMPTY);
        ParamCheckUtil.checkCollectionNonEmpty(request.getProcessNodeLinked(), ProcessErrorCodeEnum.PROCESS_NODE_LINKED_IS_EMPTY);
        ParamCheckUtil.checkCollectionNonEmpty(request.getBizConfigRelations(), ProcessErrorCodeEnum.BIZ_CONFIG_RELATION_IS_EMPTY);
        for(ProcessNodeLinkedDTO nodeLinkedDTO : request.getProcessNodeLinked()) {

            if(StrUtil.isBlank(nodeLinkedDTO.getProcessNodeName())) {
                throw new BusinessException(ProcessErrorCodeEnum.PROCESS_NODE_NAME_IS_EMPTY);
            }

            if(null == nodeLinkedDTO.getProcessNodeId()) {
                throw new BusinessException(ProcessErrorCodeEnum.PROCESS_NODE_ID_IS_EMPTY);
            }

            InvokeMethodEnum invokeMethodEnum = InvokeMethodEnum.getByCode(nodeLinkedDTO.getInvokeMethod());
            if(null == invokeMethodEnum) {
                throw new BusinessException(ProcessErrorCodeEnum.INVOKE_METHOD_IS_ERROR);
            }
        }

        // 2、保存
        processConfigService.save(request);

        return BaseResult.success();
    }

    /**
     * 删除流程
     * @param request 请求
     * @return 响应
     */
    @PostMapping("/delete")
    public BaseResult<Boolean> delete(@RequestBody DeleteProcessConfigRequest request) {
        // 1、校验入参
        ParamCheckUtil.checkStringNonEmpty(request.getName(), ProcessErrorCodeEnum.PROCESS_NAME_IS_EMPTY);

        // 2、删除
        processConfigService.delete(request.getName());

        return BaseResult.success();
    }

    /**
     * 流程配置详情
     * @param name 流程节点名称
     * @return 响应
     */
    @GetMapping("/detail")
    public BaseResult<ProcessConfigDTO> detail(String name) {
        // 1、校验入参
        ParamCheckUtil.checkStringNonEmpty(name, ProcessErrorCodeEnum.PROCESS_NAME_IS_EMPTY);

        // 2、详情
        return BaseResult.success(processConfigService.detail(name));
    }

    /**
     * 流程配置详情
     * @param name 流程节点名称
     * @return 响应
     */
    @GetMapping("/enable")
    public BaseResult<Boolean> detail(String name, Integer enable) {

        // 1、校验入参
        ParamCheckUtil.checkStringNonEmpty(name, ProcessErrorCodeEnum.PROCESS_NAME_IS_EMPTY);
        ParamCheckUtil.checkIntAllowableValues(enable, ProcessEnableEnum.allowableValues(),ProcessErrorCodeEnum.PROCESS_ENABLE_IS_ERROR);

        // 2、启用/禁用
        processConfigService.enable(name, enable);

        return BaseResult.success();
    }


    /**
     * 流程配置列表查询
     * @return 响应
     */
    @GetMapping("/list")
    public BaseResult<List<ProcessConfigDTO>> list() {
        return BaseResult.success(processConfigService.list(ProcessEnableEnum.all()));
    }

    /**
     * 发布流程
     */
    @GetMapping("/release")
    public BaseResult<Boolean> release() throws Exception {
        processConfigService.release();
        return BaseResult.success(true);
    }

}
